Skip to content

feat(manifest): add per-file digest provenance - #87

Draft
stacknil wants to merge 4 commits into
mainfrom
stacknil/issue-84-per-file-digest-provenance
Draft

feat(manifest): add per-file digest provenance#87
stacknil wants to merge 4 commits into
mainfrom
stacknil/issue-84-per-file-digest-provenance

Conversation

@stacknil

@stacknil stacknil commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #84.

  • Add input_file_digests and config_file_digests to every primary run manifest.
  • Hash each file's exact shipped bytes with SHA-256; no YAML parsing or reserialization.
  • Normalize keys to repository-relative POSIX paths and emit them in lexical order.
  • Preserve the existing input_digest and config_digest aggregate contract.
  • Pin manifest-covered shipped text inputs/configs to LF with .gitattributes so exact-byte values reproduce across Windows and Linux clean clones.
  • Keep structured artifact diff reporting (Add structured artifact-contract diff reporting #85) out of scope.

Design decision

The legacy aggregate digests remain label-sorted and LF/CRLF-normalized for UTF-8 text. Per-file digests use read_bytes() directly and are keyed by canonical repository-relative paths. A bounded LF checkout contract makes those shipped bytes platform-stable; the per-file algorithm itself does not normalize line endings. The schema keeps the new maps optional so older run-manifest/v1 consumers remain readable while current writers always emit them.

Main risk

The LF checkout contract renormalizes four historical CRLF/mixed tracked input/config files at the Git blob boundary. Parsed content is unchanged, aggregate digest values remain unchanged, and the resulting per-file values are now reproducible across clean clones.

Compatibility impact

Additive manifest fields only. Existing aggregate digest values are asserted against the v1.2 contract, a legacy manifest without per-file maps remains schema-valid, and current writers emit exact-byte maps for all six primary manifests.

Rollback path

Revert the four commits in order, or stop consuming the optional per-file maps; input_digest and config_digest remain unchanged. If the LF checkout contract must be reverted, regenerate manifests on the chosen repository byte contract before publishing.

Validation

  • python -m pytest -q — 196 passed locally.
  • PR CI — 2 test jobs and 2 Repo Sentinel jobs passed.
  • python scripts/regenerate_artifacts.py --check — 29 strict artifacts matched; 6 visual snapshots smoke-generated.
  • Independent clean-clone consumer reproduction — all 6 manifests rehashed from read_bytes() with sorted path checks passed.
  • Exact-byte, line-ending sensitivity, lexical ordering, multi-file sensitivity, and legacy compatibility tests pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add per-file digest provenance to run_manifest

1 participant